import json
import re

from django.shortcuts import render, redirect, reverse
from django.http import  Http404, HttpResponseForbidden, JsonResponse
from django_redis import get_redis_connection
from .models import User
from django.db.models import F, Q
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login as _login
from django.views import View
from utils.response_code import ResultResponse, Code
from .forms import LoginForm
from news.models import Tag, HotNews, News


def anti_crawler(func):
    ip_times = {}
    def inner(request, *args, **kwargs):
        user_ip = request.META.get("REMOTE_ADDR")
        time = ip_times.get(user_ip, 0)
        print(time)
        if time > 10:
            return HttpResponseForbidden("访问次数过于频繁！！！")
        else:
            time += 1
            ip_times[user_ip] = time
            return func(request)
    return inner


# Create your views here.
def index(request):
    # 只显示name
    tags = Tag.objects.only("name").filter(is_delete=False)
    hot = HotNews.objects.select_related("news").only("news__title", "news__image_url").order_by("priority")
    # 依据点击量
    # hot = News.objects.only("title", "image_url", "update_time", "author__username", "tag__name").\
    #     select_related("tag", "author").order_by("-clicks")[0:2]
    return render(request, "news/index.html", context={'tags': tags, 'hot': hot})


class LoginView(View):
    def get(self, request):
        if request.user.is_authenticated:
            return redirect("/index/")
        return render(request, 'users/login.html')

    def post(self, request):
        login_data = request.body
        print(login_data)
        if not login_data:
            return ResultResponse(errno=Code.ERRPARAMS, errmsg="參數錯誤")
        login_data = json.loads(login_data)
        # 使用表單驗證
        form = LoginForm(data=login_data, request=request)
        if form.is_valid():
            return ResultResponse(errmsg="恭喜你，登录成功")
        else:
            err_list = []
            for i in form.errors.get_json_data().values():
                print(form.errors.get_json_data())
                err_list.append(i[0].get('message'))
            err_str = "/".join(err_list)
            return ResultResponse(errno=Code.ERRPARAMS, errmsg=err_str)



def logout(request):
    if request.user.is_authenticated:
        request.session.flush()
    return redirect("/index/")


class RegisterView(View):
    def get(self, request):
        if request.user.is_authenticated:
            return redirect("/index/")
        return render(request, 'users/register.html')

    def post(self, request):
        data = request.body
        print(request.POST)
        print(data)
        data = json.loads(data)
        print(data)
        # 取参数
        username = data.get("username")
        password = data.get("password")
        repwd = data.get("repassword")
        mobile = data.get("mobile")
        sms_text = data.get("sms_text")
        data = request.POST
        # username = data.get("username")
        # password = data.get("password")
        # repwd = data.get("repassword")
        # mobile = data.get("mobile")
        # sms_text = data.get("sms_text")

        # 判断是否为空
        if not all([username, password, repwd, mobile, sms_text]):
            print(1)
            return HttpResponseForbidden("填写数据不完整")
        # 用户名格式

        print(re.match("^\w{5,20}$", username), username)
        if not re.match("^\w{5,20}$", username):
            print(2)
            return HttpResponseForbidden("用户名格式错误")
        # 用户名唯一性
        if User.objects.filter(username=username).count() > 0:
            return HttpResponseForbidden("用户名已经存在")
        # 密码
        if not re.match("^\w{8,20}$", password):
            print(3)
            return HttpResponseForbidden("密码格式错误")
        # 确认密码
        if repwd != password:
            print(4)
            return HttpResponseForbidden("密码不一致")
        # 手机号格式
        if not re.match("^1[3-9]\d{9}$", mobile):
            print(5)
            return HttpResponseForbidden("手机号格式错误")
        # 手机号唯一性
        if User.objects.filter(mobile=mobile).count() > 0:
            print(6)
            return HttpResponseForbidden("手机号已存在")
        # 短信验证码
        # 从数据中获取对应的短信验证码
        redis_cli = get_redis_connection("image-verify")
        sms_text_server = redis_cli.get("sms_%s" % mobile)
        if not sms_text_server:
            print(7)
            return HttpResponseForbidden("短信验证码已经过期")
        # 找到后，删除短信验证码，能且只能验证一次
        redis_cli.delete("sms_%s" % mobile)
        redis_cli.delete("send_flag_%s" % mobile)
        # 判断是否正确
        sms_text_server = sms_text_server.decode()
        if sms_text_server != sms_text:
            print(8)
            return HttpResponseForbidden("短信验证码错误")

        # 上述都通过验证后，就可以开始创建用户了
        # 创建用户对象
        user = User.objects.create_user(
            username=username,
            password=password,
            mobile=mobile
        )
        # 状态保持
        _login(request, user)
        return ResultResponse(errmsg="恭喜你，注册成功！")



